﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using Microsoft.Research.Kinect.Nui;

namespace KinnectInput
{
    public enum KinectInputState
    {
        Still,
        Forward,
        Left, 
        Right,
        ForwardLeft,
        ForwardRight,
        Menu
    }
    public class KinectCuadrantDebuger
    {
        Vector2 StartCuadrant;
        Vector2 EndCuadrant;
        Vector2 HeadScreen;
        Vector2 ScreenCenter;
        Rectangle SizeRect;
        Texture2D CuadText;
        Texture2D LineText;
        Texture2D RightZoneTex;
        Texture2D LeftZoneTex;
        Texture2D AdvanceZoneTex;
        GraphicsDevice gDevice;
        Rectangle advanceZone;
        Rectangle LeftZone;
        Rectangle RightZone;
        Rectangle OverHeadZone;
        KinectFlatInteraction hands;
        public bool ultraDebug { set; get; }
        public bool Debug { get { return false; } set { } }
        public float lastLeft;
        public float lastRight;
        public float currTime;
        public KinectInputState _state;
        public KinectInputState _finalState;
        public KinectInputState FinalState {
            get
            {
                return _finalState;
                
            }
            
            
        
        }
        public void updateState()
        {
            //lHandVec2
            if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandLeft], advanceZone))
            {
                _state = KinectInputState.Forward;
            }
            if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandLeft], advanceZone) && _state != KinectInputState.Menu)
            {
                if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], RightZone))
                {
                    _state = KinectInputState.ForwardRight;
                }
                else if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], LeftZone) && _state != KinectInputState.Menu)
                {
                    _state = KinectInputState.ForwardLeft;
                }
                else
                {
                    _state = KinectInputState.Forward;
                //lastLeft = 0;
                //lastRight = 0;
                }
            }
            else if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], RightZone) && _state != KinectInputState.Menu)
            {
                _state = KinectInputState.Right;
            }
            else if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], LeftZone) && _state != KinectInputState.Menu)
            {
                _state = KinectInputState.Left;
            }
            

            else if (_state != KinectInputState.Menu)
            {
             
                    _state = KinectInputState.Still;
                //lastLeft = 0;
                //lastRight = 0;
            }

            #region _finalState

            _finalState = _state;

            if (_state == KinectInputState.Left || _state == KinectInputState.ForwardLeft)
            {
                if (lastLeft > 0 && currTime > lastLeft + 500)
                {
                    _finalState = _state;
                }
                else
                {
                    if (_state == KinectInputState.Left)
                        _finalState = KinectInputState.Still;
                    if (_state == KinectInputState.ForwardLeft)
                        _finalState = KinectInputState.Forward;
                }
            }

            else if (_state == KinectInputState.Right || _state == KinectInputState.ForwardRight)
            {
                if (lastRight > 0 && currTime>lastRight+500)
                {
                    _finalState = _state;
                }
                else
                {
                    if (_state == KinectInputState.Right)
                        _finalState = KinectInputState.Still;
                    if (_state == KinectInputState.ForwardRight)
                        _finalState = KinectInputState.Forward;
                }
            }
            else if (_state == KinectInputState.Forward)
            {
                _finalState = KinectInputState.Forward;
            }
            //nunca deveria de darse esto


            #endregion _finalState

        }
        
        public KinectCuadrantDebuger(GraphicsDevice gDevice, KinectFlatInteraction hands)
        {
            CuadText = TextureCreator.GenerateTexture(gDevice, new Color(0, 0, 0, 50));
            LineText = TextureCreator.GenerateTexture(gDevice, new Color(255, 0, 0, 50));
            AdvanceZoneTex = TextureCreator.GenerateTexture(gDevice, new Color(255, 0, 0, 50));
            LeftZoneTex = TextureCreator.GenerateTexture(gDevice, new Color(0, 255, 0, 50));
            RightZoneTex = TextureCreator.GenerateTexture(gDevice, new Color(0, 0, 255, 50));
            this.hands = hands;
            this.gDevice=gDevice;
                        
            this.SizeRect = new Rectangle();
            ScreenCenter.X = gDevice.Viewport.Bounds.Center.X;
            ScreenCenter.Y = gDevice.Viewport.Bounds.Center.Y;

            advanceZone = new Rectangle();
            RightZone = new Rectangle();
            LeftZone = new Rectangle();
            OverHeadZone = new Rectangle();
        }
        public void Update(Vector2 Head, Vector2 Waist, GameTime gameTime, bool isUpDateState)
        {
            //float size = (Head.Y - Waist.Y  );
            float size = (Waist.Y - Head.Y );
            //StartCuadrant.X = Head.X - (size / 2);
            StartCuadrant.Y = Head.Y ;
            EndCuadrant = new Vector2(size, size);
            SizeRect.X = (int)(gDevice.Viewport.Bounds.X);
            //SizeRect.Y = (int)(gDevice.Viewport.Bounds.Center.Y+(HeadScreen.Y/2));
            SizeRect.Y = (int)(Head.Y);
            SizeRect.Width = (int)gDevice.Viewport.Bounds.Width;
            SizeRect.Height = (int)size;

            advanceZone.X = SizeRect.X;
            advanceZone.Y = SizeRect.Y;
            //advanceZone.Width = SizeRect.Center.X + (int)(HeadScreen.X / 2);
            advanceZone.Width = (int)(Head.X);
            advanceZone.Height =(int)(SizeRect.Height );

            int thirdPart = (int) (SizeRect.Height /3);

            LeftZone.X= SizeRect.X;
            //LeftZone.Y =(int)Head.Y+(SizeRect.Height/3)*2;
            LeftZone.Y = (int)Head.Y + (SizeRect.Height / 3);
            //LeftZone.Width = SizeRect.Center.X + (int)(HeadScreen.X / 2 - LeftZone.X);
            LeftZone.Width = (int)(Head.X + (size / 3));
            LeftZone.Height = SizeRect.X + (SizeRect.Height / 3)*2;



            RightZone.X = (int)Head.X + (SizeRect.Height / 3)*2;
            RightZone.Y = (int)Head.Y + (SizeRect.Height / 3);
            RightZone.Width = gDevice.Viewport.Bounds.Width - RightZone.X;
            RightZone.Height = SizeRect.X + (SizeRect.Height / 3)*2;

            OverHeadZone.X = gDevice.Viewport.Bounds.X;
            OverHeadZone.Y = gDevice.Viewport.Bounds.Y;
            OverHeadZone.Width = gDevice.Viewport.Bounds.Width;
            OverHeadZone.Height = SizeRect.Y - OverHeadZone.Y;
            currTime = (float)gameTime.TotalGameTime.TotalMilliseconds;

            if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], RightZone) && (_state != KinectInputState.Right && _state != KinectInputState.ForwardRight))
            {
                lastRight = currTime;
            }
            else if (CheckCuadrant(hands.skellManager.JointPosition[JointID.HandRight], LeftZone) && (_state != KinectInputState.Left && _state != KinectInputState.ForwardLeft))
            {
                lastLeft = currTime;
            }
            //asi hago el pudate de comprobacion desde dentro y puedo hacer lo del tiempo en el get

            if(isUpDateState)
                updateState();
        }
        public void Draw(SpriteBatch sBatch)
        {
            sBatch.Draw(CuadText, SizeRect, Color.White);

            //splitVerticaly
            int startX = (int)SizeRect.X + (SizeRect.Width / 2);
            int startY = SizeRect.Y;
            Rectangle CentralVLine = new Rectangle(SizeRect.Center.X+(int)(HeadScreen.X/2), SizeRect.Y, 1, SizeRect.Height);
            Rectangle LeftVLine=new Rectangle(SizeRect.Center.X+(int)(HeadScreen.X/2)-(SizeRect.Height/2),SizeRect.Y,1,SizeRect.Height);
            Rectangle RightVLine = new Rectangle(SizeRect.Center.X + (int)(HeadScreen.X / 2) + (SizeRect.Height / 2), SizeRect.Y, 1, SizeRect.Height);
            Rectangle TopHLine = new Rectangle((int)SizeRect.X, SizeRect.Y, SizeRect.Width, 1);
            Rectangle TopInteraction = new Rectangle(SizeRect.X ,SizeRect.Y+ SizeRect.Height/3, SizeRect.Width, 1);
            Rectangle BotomInteraction = new Rectangle(SizeRect.X, SizeRect.Y + ((SizeRect.Height / 4)*3), SizeRect.Width, 1);
            
            sBatch.Draw(LineText, CentralVLine, Color.White);
            sBatch.Draw(LineText, TopHLine, Color.White);
            sBatch.Draw(LineText, TopInteraction, Color.White);
            sBatch.Draw(LineText, BotomInteraction, Color.White);
            sBatch.Draw(LineText, LeftVLine, Color.White);
            sBatch.Draw(LineText, RightVLine, Color.White);

            switch (FinalState)
            {
                case KinectInputState.Forward:
                    Texture2D tex1 = TextureCreator.GenerateTexture(gDevice, new Color( 255,0, 0, 100));
                    sBatch.Draw(tex1, advanceZone, Color.White);
                    break;

                case KinectInputState.Left:
                    Texture2D tex2 = TextureCreator.GenerateTexture(gDevice, new Color(0, 255, 0, 100));
                    sBatch.Draw(tex2, LeftZone, Color.White);
                    break;

                case KinectInputState.Right:
                    Texture2D tex3 = TextureCreator.GenerateTexture(gDevice, new Color(0, 255, 255, 100));
                    sBatch.Draw(tex3, RightZone, Color.White);
                    break;
                case KinectInputState.Menu:
                    Texture2D tex4 = TextureCreator.GenerateTexture(gDevice, new Color(255, 255, 10, 100));
                    sBatch.Draw(tex4, OverHeadZone, Color.White);
                    break;
                    
            }
            
            if (ultraDebug)
            {
                //rHandVec2
                sBatch.Draw(TextureCreator.GenerateTexture(gDevice, Color.Black), new Rectangle((int)this.hands.skellManager.JointPosition[JointID.HandRight].X, (int)this.hands.skellManager.JointPosition[JointID.HandRight].Y, 20, 20), Color.White);
                sBatch.Draw(TextureCreator.GenerateTexture(gDevice, Color.Black), new Rectangle((int)this.hands.skellManager.JointPosition[JointID.HandLeft].X, (int)this.hands.skellManager.JointPosition[JointID.HandLeft].Y, 20, 20), Color.White);
                sBatch.Draw(AdvanceZoneTex, advanceZone, Color.White);
                sBatch.Draw(LeftZoneTex, LeftZone, Color.White);
                sBatch.Draw(RightZoneTex, RightZone, Color.White);
                sBatch.Draw(LeftZoneTex, OverHeadZone, Color.Red);
            }
        }
        private bool CheckCuadrant(Vector2 pos, Rectangle r)
        {

            return r.Contains(new Point((int)pos.X, (int)pos.Y));
        }

    }
}
